package com.llmcu.trial.completablefuture;


import lombok.extern.slf4j.Slf4j;

import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

@Slf4j
public class CompletableFutureMulCallableExample {

    public static void main(String[] args) throws InterruptedException {
        log.info("program start========");
        // 定义任务
        Supplier<String> task = () -> {
            Random random = new Random();
            int seconds = random.nextInt(5);
            try {
                TimeUnit.SECONDS.sleep(seconds+1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            log.info("Task [{}] completed after {} seconds*********************", Thread.currentThread().getName() , seconds+1);
            return Thread.currentThread().getName();

        };

        // 创建多个 CompletableFuture 来并行执行任务
        CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(task);
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(task);
        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(task);
        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(task);

        // 不重新=原来的值会对结果有影响
        future1 = future1.thenApply(result -> "Task: " + result);
        future2 =future2.thenApply(result ->"Task: " + result);
        future3 =future3.thenApply(result ->"Task: " + result);

        // 将所有异步任务组合在一起，并等待它们完成
//        CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2, future3);
        CompletableFuture<Object> allFutures = CompletableFuture.anyOf(future1, future2, future3);

        // 当所有任务都完成时，执行一些操作
        allFutures.thenRun(() -> log.info("all tasks completed***************"));

        // 等待所有任务完成（阻塞主线程）
        try {
            Object o = allFutures.get();
            log.info("return value: [{}]",o.toString());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        TimeUnit.SECONDS.sleep(10);
        log.info("main thread completed============");
    }

}
